package one.stand.service.impl;

import cn.hutool.core.img.ImgUtil;
import com.jmp.autocofiguration.util.OssUtil2;
import lombok.extern.slf4j.Slf4j;
import one.stand.advice.ResultEnum;
import one.stand.enums.LoginEnum;
import one.stand.mapper.AdminMapperExt;
import one.stand.mapper.UserLoginWxMapperExt;
import one.stand.mapper.UserMapperExt;
import one.stand.model.Admin;
import one.stand.model.SysDictValue;
import one.stand.model.User;
import one.stand.model.UserLoginWx;
import one.stand.service.UserService;
import one.stand.service.sys.SysDictValueService;
import one.stand.service.user.UserAdminService;
import one.stand.util.AssertUtil;
import one.stand.util.Md5Util;
import one.stand.util.OneListUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author cjr
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {


    @Autowired
    private UserAdminService userAdminService;
    @Autowired
    private SysDictValueService sysDictValueService;

    @Autowired
    private UserMapperExt userMapperExt;
    @Autowired
    private AdminMapperExt adminMapperExt;
    @Autowired
    private UserLoginWxMapperExt userLoginWxMapperExt;

    @Override
    @Async("asyncServiceExecutor")
    public void updateImgToLocal() {
        List<User> userList = userMapperExt.selectWXPhoto();
        log.info("wxPhoto record count:{}", userList.size());
        InputStream inputStream;
        for (User user : userList) {
            log.info("wxPhoto url:{}", user.getAvatarUrl());
            //上传oss
            inputStream = readImg(user.getAvatarUrl());
            if (inputStream == null) {
                continue;
            }
            String urlResult = OssUtil2.upload(inputStream, OssUtil2.FileSuffix.jpg);
            //插入备份表数据
            userMapperExt.insetBakData(user.getUserId());
            //更新原user表photo
            User userUpdate = new User();
            userUpdate.setUserId(user.getUserId());
            userUpdate.setAvatarUrl(urlResult);
            update(userUpdate);
//            chatFeign.save(ChatSaveDto.builder().userId(user.getUserId()).build());
        }
    }

    @Override
    public Integer saveAdmin(Admin model) {
        String loginName = model.getLoginName();

        Admin adminModel = null;
        if (StringUtils.isNotBlank(loginName)){
            adminModel = adminMapperExt.selectByName(loginName);
        }else{
            Integer adminId = model.getAdminId();
            if(adminId !=null){
                adminModel = adminMapperExt.selectByPrimaryKey(adminId);
            }
        }
        if (Objects.nonNull(model.getAdminId())) {
            AssertUtil.nonNull(adminModel, ResultEnum.PARAM_CHECK, "管理员账号不存在~！");
            AssertUtil.isTrue(adminModel.getAdminId().equals(model.getAdminId()), ResultEnum.PARAM_CHECK, "管理员账号重复~！");
        } else {
            AssertUtil.isNull(adminModel, ResultEnum.PARAM_CHECK, "管理员账号重复~！");
        }

        if (Objects.isNull(model.getAdminId())) {
            AssertUtil.nonNull(model.getPassWord(), ResultEnum.PARAM_CHECK, "请输入管理员密码~！");
            model.setPassWord(Md5Util.md5(model.getPassWord()));
            model.setCreateTime(new Date());
            model.setIsDel(0);
            adminMapperExt.insertSelective(model);
            return model.getAdminId();
        } else {
            if (StringUtils.isNoneBlank(model.getPassWord())) {
                model.setPassWord(Md5Util.md5(model.getPassWord()));
            }
            adminMapperExt.updateByPrimaryKeySelective(model);
        }
        return model.getAdminId();
    }

    @Override
    @Transactional
    public void saveUser(User user) {

        user.setAvatarUrl(getAvatarUrl(user.getAvatarUrl()));

        String nickName;
        if (StringUtils.isNoneBlank(user.getNickeName())) {
            nickName = user.getNickeName();
        } else {
            Integer id = userMapperExt.selectMaxId() + 1;
            nickName = UserAdminService.DEFAULT_NAME + id;
        }
        if (StringUtils.isBlank(user.getAvatarUrl())) {
            user.setAvatarUrl(UserAdminService.DEFAULT_IMG);
        }
        user.setNickeName(encode(nickName));

        user.setIsDel(0);
        user.setCreateTime(new Date());
        userMapperExt.insertSelective(user);

//        CreateRequest request = CreateRequest.builder()
//                .accid(String.valueOf(user.getUserId()))
//                .name(nickName)
//                .icon(user.getAvatarUrl())
//                .token("123456")
////                    .mobile(user.getPhone())
//                .gender(user.getGender())
////                    .ex(CreateRequest.Ex.builder().wechatId("wx123").build())
//                .build();
//        CreateResponse createResponse = imClient.create(request);
//        if (Objects.nonNull(createResponse)) {
//            User userUpdate = new User();
//            userUpdate.setUserId(user.getUserId());
//            userUpdate.setHasim(1);
//            userMapperExt.updateByPrimaryKeySelective(userUpdate);
//        }
    }

    @Override
    @Transactional
    public void saveUserLoginWx(Integer userId, Integer clientType, String companyKey, String openId) {
        UserLoginWx userLoginWx = userLoginWxMapperExt.select(userId, companyKey, clientType);
        if (Objects.isNull(userLoginWx) && StringUtils.isNoneBlank(openId)) {

            //同一用户不同身份时，删除前记录
            userLoginWx = userLoginWxMapperExt.selectByOpenId(clientType, companyKey, openId);
            if (Objects.nonNull(userLoginWx)) {
                userLoginWxMapperExt.deleteByPrimaryKey(userLoginWx.getId());
            }

            userLoginWx = new UserLoginWx();
            userLoginWx.setUserId(userId);
            userLoginWx.setClientType(clientType);
            userLoginWx.setCompanyKey(companyKey);
            userLoginWx.setOpenId(openId);
            userLoginWxMapperExt.insertSelective(userLoginWx);
        }
    }

    @Override
    @Transactional
    public void deleteById(Integer userId) {
        userMapperExt.deleteByPrimaryKey(userId);
    }

    @Override
    @Transactional
    public void deleteByOpenId(String openId) {
        List<User> users = userMapperExt.selectErrorUser(openId);
        if (OneListUtil.isNotEmpty(users)) {
            for (User user : users) {
                userMapperExt.deleteByPrimaryKey(user.getUserId());
                userLoginWxMapperExt.deleteByUserId(user.getUserId());
            }
        }
    }

    @Override
    @Transactional
    public void merge(Integer mergeUserId, Integer userId) {
        User user = userAdminService.getByUserId(mergeUserId);
        AssertUtil.nonNull(user, ResultEnum.PARAM_CHECK);
        AssertUtil.nonNull(user.getThirdCompanyKey(), ResultEnum.PARAM_CHECK);
        AssertUtil.nonNull(user.getOpenId(), ResultEnum.PARAM_CHECK);

        User user2 = userAdminService.getByUserId(userId);
        AssertUtil.nonNull(user2, ResultEnum.PARAM_CHECK);
        AssertUtil.isNull(user2.getThirdUserOpenId(), ResultEnum.PARAM_CHECK);

        User userUpdate = new User();
        userUpdate.setUserId(userId);
        userUpdate.setThirdUserOpenId(user.getOpenId());
        int i = userMapperExt.updateByPrimaryKeySelective(userUpdate);
        AssertUtil.isTrue(i == 1, ResultEnum.FAIL);

        i = userMapperExt.deleteByPrimaryKey(mergeUserId);
        AssertUtil.isTrue(i == 1, ResultEnum.FAIL);

        List<UserLoginWx> userLoginWxList = userLoginWxMapperExt.selectList(mergeUserId, LoginEnum.USER.getAccountType());
        for (UserLoginWx userLoginWx : userLoginWxList) {
            saveUserLoginWx(userId, userLoginWx.getClientType(), userLoginWx.getCompanyKey(), userLoginWx.getOpenId());
        }
    }

    @Override
    @Transactional
    public void update(User user) {

        user.setAvatarUrl(getAvatarUrl(user.getAvatarUrl()));

//        if (StringUtils.isNoneBlank(user.getNickeName()) || StringUtils.isNoneBlank(user.getAvatarUrl())) {
//            UpdateRequest request = UpdateRequest.builder()
//                    .accid(String.valueOf(user.getUserId()))
//                    .name(user.getNickeName())
//                    .icon(user.getAvatarUrl())
//                    .mobile(user.getPhone())
//                    .gender(user.getGender()).build();
//            imClient.update(request);
//        }

        if (StringUtils.isNoneBlank(user.getNickeName())) {
            user.setNickeName(encode(user.getNickeName()));
        }
        userMapperExt.updateByPrimaryKeySelective(user);
    }

    @Override
    public User getByPasswd(String username, String passwd) {
        String key = username + ":" + passwd;
        SysDictValue sysDictValue = sysDictValueService.get(SysDictValueService.Type.SECURITY_PASSWD, key);
        Integer userId = Objects.nonNull(sysDictValue) && StringUtils.isNoneBlank(sysDictValue.getValue()) ? Integer.valueOf(sysDictValue.getValue()) : null;
        if (Objects.isNull(userId)) {
            return null;
        }
        return userAdminService.getByUserId(userId);
    }

    @Override
    public User getByUnionid(String unionid) {
        User user = userMapperExt.selectByUnionid(unionid);
        if (Objects.nonNull(user) && user.getIsDel() == 0) {
            user.setNickeName(userAdminService.decode(user.getNickeName()));
            return user;
        }
        return null;
    }

    @Override
    public User getByOpenId(LoginEnum loginEnum, String companyKey, String openId) {
        UserLoginWx userLoginWx = userLoginWxMapperExt.selectByOpenId(loginEnum.getAccountType(), companyKey, openId);
        if (Objects.nonNull(userLoginWx)) {
            return userAdminService.getByUserId(userLoginWx.getUserId());
        }
        return null;
    }

    @Override
    public User getByWx(String unionid, LoginEnum loginEnum, String companyKey, String openId) {
        User inModel = null;
        if (StringUtils.isNoneBlank(unionid)) {// 默认unionid获取用户
            inModel = getByUnionid(unionid);
        }
        if (Objects.isNull(inModel) && StringUtils.isNoneBlank(openId)) {// 统一获取
            inModel = getByOpenId(loginEnum, companyKey, openId);
        }
        return inModel;
    }

    @Override
    public User getByPhone(String phone, Integer companyId) {
        User user = userMapperExt.selectByPhone(phone, companyId);
        decode(user);
        return Objects.nonNull(user) && user.getIsDel() == 0 ? user : null;
    }

    private InputStream readImg(String imageUrl) {
        try {
            BufferedImage bufferedImage = ImgUtil.read(new URL(imageUrl));
            if (Objects.nonNull(bufferedImage)) {
                ByteArrayOutputStream os = new ByteArrayOutputStream();
                ImageIO.write(bufferedImage, OssUtil2.FileSuffix.jpg.getSuffix(), os);
                return new ByteArrayInputStream(os.toByteArray());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    private String encode(String nickName) {
        if (StringUtils.isBlank(nickName)) return StringUtils.EMPTY;
        return new String(java.util.Base64.getEncoder().encode(nickName.getBytes()), StandardCharsets.UTF_8);
    }

    private void decode(User user) {
        if (Objects.nonNull(user)) {
            user.setNickeName(userAdminService.decode(user.getNickeName()));
        }
    }

    private String getAvatarUrl(String avatarUrl) {
        if (StringUtils.isBlank(avatarUrl)) return null;

        String img = avatarUrl;
        if (StringUtils.contains(avatarUrl, "qlogo.cn")
                && StringUtils.endsWith(avatarUrl, "/132")) {//微信头像处理，更清晰
            img = StringUtils.removeEnd(avatarUrl, "/132") + "/0";
        }

//        if (StringUtils.contains(avatarUrl, "http://thirdwx.qlogo.cn/")) {//页面混合http\https,导致下载html
//            img = StringUtils.replaceAll(avatarUrl, "http://thirdwx.qlogo.cn/", "https://thirdwx.qlogo.cn/");
//        }
        return img;
    }
}
